#include <stdio.h>
#include "cmsis_os2.h"
#include "ohos_run.h"

#include "driver/gpio.h"
#include "driver/ledc.h"

#define LEDC_HS_MODE LEDC_HIGH_SPEED_MODE
#define LEDC_HS_TIMER LEDC_TIMER_0
#define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0
#define LEDC_HS_CH0_GPIO (23)

osThreadId_t pwm_id = NULL;

void pwm_task(void)
{
    gpio_config_t gpiob = {
        .intr_type = GPIO_INTR_DISABLE,
        .mode = GPIO_MODE_OUTPUT,
        .pin_bit_mask = 1ULL << GPIO_NUM_15,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_ENABLE,
    };
    gpio_config(&gpiob);

    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_TIMER_13_BIT,
        .freq_hz = 5000,
        .speed_mode = LEDC_HS_MODE,
        .timer_num = LEDC_HS_TIMER,
        .clk_cfg = LEDC_AUTO_CLK,
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t ledc_channel = {
        .channel = LEDC_HS_CH0_CHANNEL,
        .duty = 0,
        .gpio_num = LEDC_HS_CH0_GPIO,
        .hpoint = 0,
        .speed_mode = LEDC_HS_MODE,
        .timer_sel = LEDC_HS_TIMER};
    ledc_channel_config(&ledc_channel);

    gpio_set_level(GPIO_NUM_15, 0);

    ledc_fade_func_install(0);

    while (1)
    {
        ledc_set_fade_with_time(LEDC_HIGH_SPEED_MODE, LEDC_HS_CH0_CHANNEL, 5000, 1500);
        ledc_fade_start(LEDC_HIGH_SPEED_MODE, LEDC_HS_CH0_CHANNEL, LEDC_FADE_NO_WAIT);
        osDelay(1500 / portTICK_PERIOD_MS);

        ledc_set_fade_with_time(LEDC_HIGH_SPEED_MODE, LEDC_HS_CH0_CHANNEL, 0, 1500);
        ledc_fade_start(LEDC_HIGH_SPEED_MODE, LEDC_HS_CH0_CHANNEL, LEDC_FADE_NO_WAIT);
        osDelay(1500 / portTICK_PERIOD_MS);
    }
}

static void led_test_example(void)
{
    osThreadAttr_t attr;
    attr.name = "ledc_test_task";
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 40960;
    attr.priority = 21;
    pwm_id = osThreadNew((osThreadFunc_t)pwm_task, NULL, &attr);

    if (pwm_id == NULL)
    {
        printf("failed to create led task!\r\n");
    }
}

OHOS_APP_RUN(led_test_example);